export interface iTrie {}

export class Trie {
  public root: Node;
  constructor() {
    this.root = new Node("root");
  }

  public insert(word: string) {
    let currentNode = this.root;
    [...word].forEach((char) => {
      if (currentNode.children[char] === undefined) {
        currentNode.children[char] = new Node(char);
      }
      currentNode = currentNode.children[char];
    });

    currentNode.isWordEnd = true;
  }
  public search(word: string) {
    return this.getNode(word) !== null;
  }

  /**
   *
   * @param word
   * @returns
   */
  public getNode(word: string) {
    let currentNode = this.root;
    for (const char of word) {
      if (!currentNode.has(char)) return null;
      currentNode = currentNode.get(char)!;
    }

    return currentNode;
  }
}

class Node {
  public value: string;
  public isWordEnd: boolean = false;
  public children: { [key: string]: Node } = {};

  constructor(chr: string) {
    this.value = chr;
  }

  hasChildren() {
    return Object.keys(this.children).length > 0;
  }

  getChildren() {
    return Object.values(this.children);
  }

  has(char: string) {
    return this.children[char] !== undefined;
  }

  get(char: string): Node | undefined {
    return this.children[char];
  }
}
